from fastapi import APIRouter, Depends, Body
from starlette.responses import JSONResponse

from app.http.deps import get_db
from app.schemas.auth import Token
from app.services.auth import random_code_verifier
from app.services.auth.grant import PasswordGrant, CellphoneGrant, WXCellphoneGrant
from app.services.auth.oauth2_schema import OAuth2PasswordRequest, OAuth2CellphoneRequest, OAuth2WXCellphoneRequest, WX4CellphoneQequest
from app.services.sms import sms_sender
from app.support.helper import is_chinese_cellphone

import requests

router = APIRouter(
    prefix="/auth"
)


@router.post("/token", response_model=Token, dependencies=[Depends(get_db)])
def token(request_data: OAuth2PasswordRequest):
    """
    用户名+密码登录
    """
    grant = PasswordGrant(request_data)
    return grant.respond()


@router.post("/cellphone/token", response_model=Token, dependencies=[Depends(get_db)])
def cellphone_token(request_data: OAuth2CellphoneRequest):
    """
    手机号+验证码登录
    """
    grant = CellphoneGrant(request_data)
    return grant.respond()


@router.post("/cellphone/verification_code")
def send_verification_code(cellphone: str = Body(..., embed=True)):
    """
    发送验证码
    """
    if not is_chinese_cellphone(cellphone):
        return JSONResponse(status_code=422, content={"message": 'invalid cellphone'})

    code = random_code_verifier.make(cellphone)
    # fake send
    sms_sender.send(cellphone, {'code': code})
    return {"success": True}


@router.post("/wx/cellphone")
def cellphone_token(request_data: WX4CellphoneQequest):
    """
    请求微信小程序官方api获取微信绑定的手机号信息
    """
    url = f"https://api.weixin.qq.com/sns/jscode2session"
    params = {
        "appid": request_data.appid,
        "secret": request_data.secret,
        "js_code": request_data.js_code,
        "grant_type": request_data.grant_type,
    }

    try:
        # 发送 GET 请求到微信 API
        response = requests.get(url, params=params)
        # 检查响应状态码是否为200
        response.raise_for_status()  # 如果不是200，抛出异常

        # 解析响应的 JSON 数据
        res = response.json()

        # 检查微信 API 返回的数据是否包含 openid 和 session_key
        openid = res.get('openid')
        session_key = res.get('session_key')

        if not openid or not session_key:
            raise HTTPException(status_code=400, detail="微信返回的数据不完整")

        # 返回openid和session_key
        return {"openid": openid, "session_key": session_key}

    except requests.RequestException as e:
        raise HTTPException(status_code=500, detail=f"请求微信API失败: {str(e)}")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"发生未知错误: {str(e)}")

    result = {
        openid: res.openid,
        session_key: res.session_key
    }

    return result


@router.post("/wx/cellphone/token", response_model=Token, dependencies=[Depends(get_db)])
def cellphone_token(request_data: OAuth2WXCellphoneRequest):
    """
    微信手机号登录
    """
    grant = WXCellphoneGrant(request_data)
    return grant.respond()
